package com.ztk.util;

import org.quartz.*;
  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class CronExpressionParser {  
  
    /**  
     * 解析Cron表达式，获取下一个执行时间  
     *  
     * @param cronExpression Cron表达式  
     * @return 下一个执行时间  
     * @throws ParseException 如果Cron表达式格式不正确  
     * @throws SchedulerException 如果调度器初始化失败（在这个工具类中不会实际使用调度器）  
     */  
    public static Date getNextExecutionTime(String cronExpression) throws ParseException, SchedulerException {  
        CronExpression cron = new CronExpression(cronExpression);  
        Date now = new Date();  
        return cron.getNextValidTimeAfter(now);  
    }  
  
    /**  
     * 估算Cron表达式的周期（以毫秒为单位）  
     * 注意：这个方法只是一个估算值，因为Cron表达式的周期可能涉及复杂的时间模式  
     *  
     * @param cronExpression Cron表达式  
     * @return 估算的周期（毫秒）  
     * @throws ParseException 如果Cron表达式格式不正确  
     * @throws SchedulerException 如果调度器初始化失败（在这个工具类中不会实际使用调度器）  
     */  
    public static long estimatePeriodMillis(String cronExpression) throws ParseException, SchedulerException {  
        CronExpression cron = new CronExpression(cronExpression);  
        Date now = new Date();  
        Date nextExecutionTime = cron.getNextValidTimeAfter(now);  
          
        // 为了估算周期，我们获取下一个执行时间的下一个有效时间，并计算它们之间的差值  
        // 请注意，这种方法并不总是准确的，特别是当Cron表达式涉及月份和星期的变化时  
        Date nextNextExecutionTime = cron.getNextValidTimeAfter(nextExecutionTime);  
          
        return nextNextExecutionTime.getTime() - nextExecutionTime.getTime();  
    }  
  
    public static void main(String[] args) {  
        try {  
            String cronExpression = "0 0 1 * * ?"; // 每天凌晨1点执行  
  
            // 获取下一个执行时间  
            Date nextExecutionTime = getNextExecutionTime(cronExpression);  
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
            System.out.println("Next Execution Time: " + sdf.format(nextExecutionTime));  
  
            // 估算周期（以毫秒为单位）  
            // 注意：这个估算值可能不准确，特别是当Cron表达式涉及复杂的时间模式时  
            long estimatedPeriodMillis = estimatePeriodMillis(cronExpression);  
            System.out.println("Estimated Period (millis): " + estimatedPeriodMillis);  
            // 为了方便查看，将毫秒转换为天、小时、分钟和秒  
            long days = TimeUnit.MILLISECONDS.toDays(estimatedPeriodMillis);
            long hours = TimeUnit.MILLISECONDS.toHours(estimatedPeriodMillis) % 24;  
            long minutes = TimeUnit.MILLISECONDS.toMinutes(estimatedPeriodMillis) % 60;  
            long seconds = TimeUnit.MILLISECONDS.toSeconds(estimatedPeriodMillis) % 60;  
            System.out.println("Estimated Period: " + days + " days, " + hours + " hours, " + minutes + " minutes, " + seconds + " seconds");  
  
        } catch (Exception e) {
            e.printStackTrace();  
        }  
    }  
}